﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL;
using bitzhuwei.FeedingFrenzy.WorldModel;

namespace bitzhuwei.FeedingFrenzy
{
    /// <summary>
    /// The main form class.
    /// </summary>
    public partial class SharpGLForm : Form, IGraphics
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SharpGLForm"/> class.
        /// </summary>
        public SharpGLForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Handles the OpenGLDraw event of the openGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
        {
            //  Get the OpenGL object.
            OpenGL gl = openGLControl.OpenGL;
            //  Clear the color and depth buffer.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            if (this.seaWorld != null && this.PictureUpdated)
            {
                this.seaWorld.Draw();
            }

            if (this.me != null)
            {
                this.me.Draw(gl);
            }

            //Utility.DrawPyramid(gl, pyramid);

            Utility.DrawCube(gl, pyramid);
            Utility.DrawCube(gl, pyramidCenter);
        }



        /// <summary>
        /// Handles the OpenGLInitialized event of the openGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
        {
            //  TODO: Initialise OpenGL here.

            //  Get the OpenGL object.
            OpenGL gl = openGLControl.OpenGL;

            //  Set the clear color.
            gl.ClearColor(0, 0, 0, 0);
        }

        /// <summary>
        /// Handles the Resized event of the openGLControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void openGLControl_Resized(object sender, EventArgs e)
        {

        }

        private SharpGLController.ViewController viewController;
        private GameWorld seaWorld;


        private void SharpGLForm_Load(object sender, EventArgs e)
        {
            var gl = this.openGLControl.OpenGL;

            Utility.SetCube(gl);

            var world = new GameWorld(this);
            GameFish.LoadTextures("GameFish", gl);
            var fishes = GameFish.GetRandomFishes(100);
            world.AddRange(fishes);
            
            GameBoard.LoadTextures("Scene\\Grass.jpg", gl);
            //GameBoard.LoadTextures("Scene\\SeaBottom.png", gl);
            var bottom = GameBoard.GetInstance();
            world.Add(bottom);

            var me = GameFish.GetRandomFishes(1)[0];
            me.AutoMove = false;
            this.me = me;
            world.Add(me);

            world.Start();
            this.seaWorld = world;
#if DEBUG
            var monitor = new FormGameWorldMonitor(this.seaWorld);
            monitor.Show();
#endif
            this.viewController = new bitzhuwei.SharpGLController.ViewController(this.openGLControl);
            this.viewController.CameraChanged += new EventHandler<SharpGLController.CameraEventArgs>(viewController_CameraChanged);
            this.viewController.Start();

            Application.Idle += new EventHandler(Application_Idle);
        }

        void viewController_CameraChanged(object sender, SharpGLController.CameraEventArgs e)
        {
            this.pyramid.X = (e.center.X + e.eye.X) / 2;
            this.pyramid.Y = e.center.Y;
            this.pyramid.Z = (e.center.Z + e.eye.Z) / 2;
            this.pyramidCenter.X = (e.center.X);
            this.pyramidCenter.Y = (e.center.Y);
            this.pyramidCenter.Z = (e.center.Z);
        }

        TriTuple<double> pyramid = new TriTuple<double>(0, 0, 0);
        TriTuple<double> pyramidCenter = new TriTuple<double>(0, 0, 0);


        void Application_Idle(object sender, EventArgs e)
        {
            if (this.viewController != null)
            {
                this.lblInfo.Text = this.viewController.ToString();
            }
        }

        private bool pictureUpdated = false;
        private GameFish me;

        #region IGraphics

        public bool PictureUpdated
        {
            get
            {
                return pictureUpdated;
            }
            set
            {
                this.pictureUpdated = value;
            }
        }

        public OpenGLControl GetDrawingControl()
        {
            return this.openGLControl;
        }

        #endregion IGraphics

    }
}
